using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable UnusedParameter.Global

namespace Parse.Classes
{
    public delegate bool ParseXmlFilterDelegate(ParseXml po, string classNames);

    [Imported]
    [IgnoreNamespace]
    public sealed class ParseXml
    {
        public string tagName;
        public string tagAttr;
        public string tagEndr;

        [PreserveName, PreserveCase]
        public static void Parse(string text, ParseXmlOptions options)
        {
        }

        /// <summary>
        /// Parses the tag inner content building this tag to output as is.
        /// </summary>
        /// <param name="po">The parse object</param>
        [PreserveName, PreserveCase]
        public static void ParseInner(ParseXml po)
        {
        }

        /// <summary>
        /// Continues parsing the inner content of this tag.
        /// Does not explicitly build this tag into the output.
        /// Use ParseInner or BuildInner to build this tag into output.
        /// </summary>
        /// <param name="po">The po.</param>
        [PreserveName, PreserveCase]
        public static void ParseRecur(ParseXml po)
        {
        }

        /// <summary>
        /// Builds the tag inner content to output.
        /// Use instead of ParseInner if attributes or the tag name have been changed.
        /// </summary>
        /// <param name="po">The parse object</param>
        [PreserveName, PreserveCase]
        public static void BuildInner(ParseXml po)
        {
        }

        /// <summary>
        /// The build buffer.
        /// </summary>
        /// <returns>the buffer</returns>
        public string Buffer()
        {
            return null;
        }

        /// <summary>
        /// Appends txt to the build.
        /// </summary>
        /// <param name="txt">text to add</param>
        public void Append(string txt)
        {
            
        }

        /// <summary>
        /// Gets any front part before the tag.
        /// Same as the area between this tag and the end of the last tag.
        /// Also gets value for area method.
        /// </summary>
        /// <returns>front</returns>
        public string GetFront()
        {
            return null;
        }

        /// <summary>
        /// Gets any white space immediatly before this tag.
        /// </summary>
        /// <returns>white space</returns>
        public string GetWhite()
        {
            return null;
        }

        /// <summary>
        /// Gets the whole tag (before content and without end tag)
        /// </summary>
        /// <returns>tag</returns>
        public string GetTag()
        {
            return null;
        }

        public bool HasInner()
        {
            return false;
        }

        /// <summary>
        /// Gets the inner content of the tag if any.
        /// </summary>
        /// <returns>inner content</returns>
        public string GetInner()
        {
            return null;
        }

        /// <summary>
        /// Gets the outer content of the entire tag and end tag.
        /// </summary>
        /// <returns>outer content</returns>
        public string GetOuter()
        {
            return null;
        }

        /// <summary>
        /// Gets the end tag or empty string.
        /// </summary>
        /// <returns>end tag</returns>
        public string GetEndTag()
        {
            return null;
        }

        /// <summary>
        /// Gets an attribute value by name or empty string.
        /// </summary>
        /// <param name="n">The attribute name</param>
        /// <returns>attribute value</returns>
        public string GetAttr(string n)
        {
            return null;
        }

        /// <summary>
        /// Sets an attribute value by name.
        /// </summary>
        /// <param name="n">The attribute name</param>
        /// <param name="v">The attribute value</param>
        public void SetAttr(string n, object v)
        {
        }

        public string RemoveClass(string cls)
        {
            return null;
        }

        public string AddClass(string cls)
        {
            return null;
        }

        public Dictionary<string, string> GetStyleMap()
        {
            return null;
        }

        public string BuildTag()
        {
            return null;
        }

        public string BuildStyle()
        {
            return null;
        }

        // Requires explicitly loading ParseXmlClean.js
        [AlternateSignature]
        [PreserveName, PreserveCase]
        public static extern string Clean(string txt);

        [PreserveName, PreserveCase]
        public static string Transform(string txt, HtmlTransform map)
        {
            return null;
        }
    }

    // ReSharper disable InconsistentNaming

    [Imported]
    [IgnoreNamespace]
    public sealed class ProcessXml
    {
        public string output;
        public bool changed;

        [PreserveName, PreserveCase]
        public static ProcessXml Process(string content, XmlMap map)
        {
            return null;
        }
    }

    [IgnoreNamespace]
    public sealed class ParseXmlOptions
    {
        public Dictionary controller;
        public bool usecase;
        public bool lonely;
        [PreserveName, PreserveCase]
        public ParseXmlFilterDelegate Filter;
    }

    /// <summary>
    /// Class that serves as a map providing actions to perform for found tags.
    /// The actions are specified as lower case methods named for the tag name.
    /// For example, define a "div" method to handle parsing of div tags.
    /// </summary>
    [Imported]
    public class XmlMap
    {
        public ParseXmlOptions options;
        public int level;

        /// <summary>
        /// Executed for any tag not explicitly defined.
        /// Ignores script, style, xmp, ?, and ! tags
        /// ... add explicit definitions to include them
        /// </summary>
        /// <param name="po">The po.</param>
        [PreserveName]
        public virtual void Any(ParseXml po)
        {
            
        }

        /// <summary>
        /// Executed for any remaining area after a tag.
        /// </summary>
        /// <param name="po">The parse object</param>
        [PreserveName]
        public virtual void Area(ParseXml po)
        {

        }
    }

    [IgnoreNamespace]
    public class HtmlTransform : XmlMap
    {
        public HtmlTransform(ParseXmlOptions options)
        {
            Type.SetField(this, "options", options ?? new ParseXmlOptions());
            Type.SetField(this, "level", 1);
            Type.SetField(this, "blk", 0);
        }

        // The rest of the methods are loaded by loading Scripts/Scripts/ParseXmlClean.js
    }
}
